import { ExclamationCircleFilled } from '@ant-design/icons';
import { Modal } from 'antd';
import cloneDeep from 'lodash/cloneDeep';
import React, { useEffect, useMemo, useState } from 'react';

import { ImageToCropInfo } from '@/interface';

import styles from './index.module.less';
import Screen from './Screen';
import ToBeCropped from './ToBeCropped';
import ToBeSaved from './ToBeSaved';

export interface CropModalProps {
  open: boolean;
  // 比例是否锁定
  // 此字段在创建template时 = false，创建creative时 = true
  isRatioLocked?: boolean;
  images: Array<ImageToCropInfo>;
  onClose: () => void;
  onSave: (images: Array<ImageToCropInfo>) => void;
}

const CropProductImageModal = ({
  open,
  images,
  isRatioLocked = false,
  onSave,
  onClose
}: CropModalProps): JSX.Element => {
  // 当前裁剪图片索引
  const [croppingIndex, setCroppingIndex] = useState(0);
  // 待裁剪图片列表
  const [toBeCroppedList, setToBeCroppedList] = useState<ImageToCropInfo[]>([]);
  // 待保存图片列表
  const [toBeSavedList, setToBeSavedList] = useState<ImageToCropInfo[]>([]);

  // 当前需要裁剪的图片
  const toBeCroppedImage = useMemo(() => {
    return toBeCroppedList[croppingIndex];
  }, [croppingIndex, toBeCroppedList]);

  // 当前save按钮是否禁用
  const disabledBtn = useMemo(() => {
    return toBeSavedList.length === 0;
  }, [toBeSavedList]);

  // 移除待保存列表中的指定条目
  const removeToBeSavedItem = (deleteIndex: number): void => {
    // 从待保存列表中删除
    const savedItem = toBeSavedList.splice(deleteIndex, 1)[0];
    setToBeSavedList([...toBeSavedList]);

    // 添加到待裁剪列表中
    setToBeCroppedList([
      ...toBeCroppedList,
      {
        ...savedItem,
        src: null,
        width: null,
        height: null,
        ratio: isRatioLocked ? savedItem.ratio : null
      }
    ]);
  };

  // 执行裁剪按钮
  const saveCroppedImage = (
    cropped: [number, number, number, number],
    imageSrc: string,
    width: number,
    height: number,
    ratio: [number, number]
  ): void => {
    // 如果裁剪为中间的图片，则自动跳到下一张
    let tmpCroppedIndex = croppingIndex;

    // 如果裁剪条目为最后一个，则跳转到第一张
    if (croppingIndex === toBeCroppedList.length - 1) {
      tmpCroppedIndex = 0;
    }
    // 设置待裁剪图片索引
    setCroppingIndex(tmpCroppedIndex);

    // 移除待裁剪图片
    const removedItem = toBeCroppedList.splice(croppingIndex, 1)[0];
    setToBeCroppedList([...toBeCroppedList]);

    // 保存到待保存列表中
    setToBeSavedList([
      ...toBeSavedList,
      {
        ...removedItem,
        cropped,
        src: imageSrc,
        height,
        width,
        ratio
      }
    ]);
  };

  const handleModalSave = (): void => {
    // 获取无需裁剪的图片列表
    const noNeedCropList = (images || []).filter((image) => image.skipClip);
    const allImageList = [...noNeedCropList, ...toBeSavedList];

    if (toBeCroppedList.length > 0) {
      Modal.confirm({
        title: 'Are you sure you want to save?',
        content:
          'Some images are uncropped and will be automatically deleted. Do you want to proceed?',
        okText: 'Save',
        closable: true,
        maskClosable: true,
        icon: <ExclamationCircleFilled />,
        onOk() {
          onSave(allImageList);
        }
      });
      return;
    }

    onSave(allImageList);
  };

  useEffect(() => {
    // 从上传的图片列表中过滤出需要裁剪的图片列表
    const list = (images || []).filter((image) => !image.skipClip);
    setToBeCroppedList(cloneDeep(list));

    // 重置初始化数据
    setCroppingIndex(0);
    setToBeSavedList([]);
  }, [images, setCroppingIndex, setToBeCroppedList, setToBeSavedList, open]);

  return (
    <Modal
      open={open}
      okText="Save"
      title="Crop Image"
      onCancel={onClose}
      onOk={handleModalSave}
      okButtonProps={{ disabled: disabledBtn }}
      maskClosable={false}
      width={732}
      bodyStyle={{ padding: 0 }}
    >
      <div className={styles['crop-modal']}>
        <div className={styles.left}>
          <ToBeCropped
            toBeCroppedList={toBeCroppedList}
            croppingIndex={croppingIndex}
            setCroppingIndex={setCroppingIndex}
          />
        </div>
        <div className={styles.center}>
          <Screen
            isRatioLocked={isRatioLocked}
            toBeCroppedImage={toBeCroppedImage}
            saveCroppedImage={saveCroppedImage}
          />
        </div>
        <div className={styles.right}>
          <ToBeSaved
            toBeSavedList={toBeSavedList}
            removeToBeSavedItem={removeToBeSavedItem}
          />
        </div>
      </div>
    </Modal>
  );
};

export default CropProductImageModal;
